import React, { useState, useEffect } from 'react';
import {
  DndContext,
  closestCenter,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import {
  useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { DragOutlined } from '@ant-design/icons';
import { Tag, Space, Button, Popconfirm } from 'antd';
import { 
  CalendarOutlined, 
  CodeOutlined, 
  MinusOutlined 
} from '@ant-design/icons';
import styles from './index.module.css';

interface DraggableListProps<T> {
  dataSource: T[];
  onDragEnd?: (newData: T[]) => void;
  rowKey: string | ((record: T) => string);
  dragDisabled?: boolean;
  renderItem: (item: T, index: number) => React.ReactNode;
  renderDragHandle?: (item: T, index: number) => React.ReactNode;
  header?: React.ReactNode;
  className?: string;
}

interface DraggableItemProps {
  children: React.ReactNode;
  id: string;
  dragDisabled?: boolean;
  dragHandle?: React.ReactNode;
}

const DraggableItem: React.FC<DraggableItemProps> = ({ children, id, dragDisabled, dragHandle }) => {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id, disabled: dragDisabled });

  const style = {
    transform: CSS.Transform.toString(transform),
    transition,
    opacity: isDragging ? 0.5 : 1,
  };

  return (
    <div 
      ref={setNodeRef} 
      style={style} 
      className={`${styles.draggableItem} ${isDragging ? styles.draggableItemDragging : ''}`}
    >
      <div style={{ display: 'flex', alignItems: 'center' }}>
        {dragHandle && (
          <div {...attributes} {...listeners} className={styles.dragHandle}>
            {dragHandle}
          </div>
        )}
        <div style={{ flex: 1 }}>
          {children}
        </div>
      </div>
    </div>
  );
};

const DraggableList = <T extends Record<string, any>>({
  dataSource,
  onDragEnd,
  rowKey,
  dragDisabled = false,
  renderItem,
  renderDragHandle,
  header,
  className = '',
}: DraggableListProps<T>) => {
  const [data, setData] = useState(dataSource);

  // 监听 dataSource 的变化，同步更新内部状态
  useEffect(() => {
    setData(dataSource);
  }, [dataSource]);

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates,
    })
  );

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;

    if (active.id !== over?.id) {
      setData((items) => {
        const oldIndex = items.findIndex((item) => {
          const key = typeof rowKey === 'function' ? rowKey(item) : item[rowKey];
          return key === active.id;
        });
        const newIndex = items.findIndex((item) => {
          const key = typeof rowKey === 'function' ? rowKey(item) : item[rowKey];
          return key === over?.id;
        });

        const newData = arrayMove(items, oldIndex, newIndex);
        onDragEnd?.(newData);
        return newData;
      });
    }
  };

  return (
    <div className={`${styles.draggableList} ${className}`}>
      {header && (
        <div className={styles.draggableListHeader}>
          {header}
        </div>
      )}
      <DndContext
        sensors={sensors}
        collisionDetection={closestCenter}
        onDragEnd={handleDragEnd}
      >
        <SortableContext
          items={data.map((item) => {
            const key = typeof rowKey === 'function' ? rowKey(item) : item[rowKey];
            return key;
          })}
          strategy={verticalListSortingStrategy}
        >
          <div className={styles.draggableListContent}>
            {data.map((item, index) => {
              const key = typeof rowKey === 'function' ? rowKey(item) : item[rowKey];
              return (
                <DraggableItem 
                  key={key} 
                  id={key} 
                  dragDisabled={dragDisabled}
                  dragHandle={renderDragHandle ? renderDragHandle(item, index) : undefined}
                >
                  {renderItem(item, index)}
                </DraggableItem>
              );
            })}
          </div>
        </SortableContext>
      </DndContext>
    </div>
  );
};

export default DraggableList; 